package com.example.demodb.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

@Entity
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
@Table(name = "song")
public class Song {
    @Column//加了@column后,就会在数据库中自动生成  user_id 这种命名格式的键
    @Id
    private String id;
    @Column
    private String title;
    @Column
    private String artist;
    //应该是指发行的专辑,本来是命名为release，但是好像冲突了。不能起这个名字
    @Column
    private String album;
    //歌曲的音源url（用base64编码）
    @Column
    private String songUrl = "1";
    //歌曲的图片url（用base64编码）
    @Column
    private String imageUrl = "1";
    //歌曲的歌词
    @Column
    private String lrc="1";
    //歌曲的类别、流派
    @Column
    private String style="1";

    @OneToMany(mappedBy = "song", cascade = CascadeType.ALL)
    @JsonIgnore
    private Set<UserSong> userSongs;

    @OneToMany(mappedBy = "song", cascade = CascadeType.ALL)
    @JsonIgnore
    private Set<UserLove> userLoves;


    //song1 与 song2List 歌相似 (本体）
    @OneToMany(mappedBy = "song1", cascade = CascadeType.ALL)
    @JsonIgnore
    private Set<SongSong> song1Song2s;

    //song2 与 song1List 歌相似
    @OneToMany(mappedBy = "song2", cascade = CascadeType.ALL)
    @JsonIgnore
    private Set<SongSong> song2Song1s;



    public UserSong findUserSong(User user){
        AtomicReference<UserSong> result = new AtomicReference<>(null);
        userSongs.forEach(userSong -> {
            if(userSong.getUser().equals(user))
                result.set(userSong);
        });
        return result.get();
    }

    public UserLove findUserLove(User user) {
        AtomicReference<UserLove> result = new AtomicReference<>(null);
        userLoves.forEach(userLove -> {
            if(userLove.getUser().equals(user))
                result.set(userLove);
        });
        return result.get();
    }

    public SongSong findSongSong(Song song1){
        AtomicReference<SongSong> result = new AtomicReference<>(null);
        song2Song1s.forEach(songsong -> {
            if(songsong.getSong1().equals(song1))
                result.set(songsong);
        });
        return result.get();
    }

    public SongSong addSongSong(Song song2, Double sim){
        SongSong songSong = song2.findSongSong(this);
        if(songSong != null){
            return songSong;
        }
        songSong = new SongSong();
        songSong.setSong1(this);
        songSong.setSong2(song2);
        songSong.setSim(sim);
        song1Song2s.add(songSong);
        return songSong;
    }

    public SongSong changeSim(SongSong songSong, Double sim) {
        songSong.setSim(sim);
        return songSong;
    }


}
